package cn.csc.module.pay.util;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.google.common.base.Joiner;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.TreeMap;

/**
 * 支付接口参数验签工具类
 * @author liuchuang
 * @version 1.0
 * @date 2023/7/12 17:16
 * @modify
 */
@Slf4j
public class SignUtils {

    /**
     * 对参数进行签名，会过滤掉空属性及Map或List等复杂对象
     * 签名字符串格式为：appId&k1=v1&...&appSecret
     * @param params 签名参数
     * @param appSecret 应用密钥
     * @return
     */
    public static String signDebug(Object params, String appSecret) {
        log.info("[signDebug]签名参数：{}", params.toString());
        JSONObject body = JSONObject.parseObject(JSON.toJSONString(params), Feature.OrderedField);

        TreeMap<String, String> map = new TreeMap<>();
        //过滤掉appId字段，空属性及Map或List等复杂对象
        body.entrySet().stream().filter(p -> !"appId".equals(p.getKey()) && p.getValue() != null && !"".equals(p.getValue()) && !(p.getValue() instanceof Map) && !(p.getValue() instanceof Iterable)).forEach(p -> map.put(p.getKey(), p.getValue().toString()));
        //拼接appSecret
        String temp = body.getString("appId")+Joiner.on("&").withKeyValueSeparator("=").join(map).concat("&").concat(appSecret);
        String sign = SecureUtil.md5(temp);
        log.info("[signDebug]签名结果：{}", sign);
        return sign;
    }

    /**
     * 对参数进行签名，会过滤掉空属性及Map或List等复杂对象
     *
     * @param params 签名参数
     * @param appSecret 应用密钥
     * @return
     */
    public static String sign(Object params, String appSecret) {
        JSONObject body = JSONObject.parseObject(JSON.toJSONString(params), Feature.OrderedField);

        TreeMap<String, String> map = new TreeMap<>();
        //过滤掉key，appId字段，空属性及Map或List等复杂对象
        body.entrySet().stream().filter(p -> !"appId".equals(p.getKey()) && p.getValue() != null && !"".equals(p.getValue()) && !(p.getValue() instanceof Map) && !(p.getValue() instanceof Iterable)).forEach(p -> map.put(p.getKey(), p.getValue().toString()));
        //拼接secret
        String temp = body.getString("appId")+Joiner.on("&").withKeyValueSeparator("=").join(map).concat("&").concat(appSecret);
        return SecureUtil.md5(temp);
    }


}
